using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using ValidationFramework.Extensions;

namespace ValidationFramework.Reflection
{
	public class CachedParameterInfo : CachedInfoBase
	{
		internal CachedParameterInfo(ParameterInfo parameterInfo)
			: base(parameterInfo.ParameterType.TypeHandle, parameterInfo.Name)
		{
			if (parameterInfo.IsOutParam())
			{
				var memberInfo = parameterInfo.Member;
				var declaringType = memberInfo.DeclaringType;
				throw new ArgumentException(string.Format("Cannot apply rules to an 'out' parameter. Type = '{0}'. Method = '{1}'. Parameter = '{2}'", declaringType.ToUserFriendlyString(), memberInfo.Name, parameterInfo.Name), "parameterInfo");
			}
			Position = parameterInfo.Position;
		}

		public RuntimeMethodHandle ParentMethodHandle
		{
			get;
			private set;
		}
		/// <summary>
		/// The position of the <see cref="ParameterDescriptor"/> in the methods signature.
		/// </summary>
		public int Position
		{
			get;
			private set;
		}

		/// <inheritdoc />
		public override object GetValue(object target)
		{
			Guard.ArgumentNotNull(target, "target");
			if (target is MethodCall)
			{
				var MethodCall = (MethodCall)target;
				return MethodCall[Position];
			}
			else
				throw new InvalidOperationException("Can only get the value of a cached parameter when given an instance of 'MethodCall'");
		}
	}
}
